#include "Worker.hpp"


#include "../common/definitions.h"

#ifndef STATIC_ALLOC
extern double (* A)[2][Npadded][Npadded][Npadded];
extern double (* Acheck)[2][Npadded][Npadded][Npadded];
#else
extern double A[1][2][Npadded][Npadded][Npadded] __attribute__ ((aligned(16)));
extern double Acheck[1][2][Npadded][Npadded][Npadded] __attribute__ ((aligned(16)));
#endif // STATIC_ALLOC


#define __COUNTING_DEP_EXTERN_DECL__
#include "AutoGenSupport.hpp"
//extern swarm_Dep_t dep;
RSTREAM_COUNTING_DEP_EXTERN_DECL(0, 7, 3)
#undef __COUNTING_DEP_EXTERN_DECL__

#define __EDT_DEF__
#include "AutoGenSupport.hpp"
//swarm_CodeletDesc_IMPL_NOCANCEL(heat3d, heat3d, swarm_c_void, swarm_c_void)
RSTREAM_BEGIN_WORKER_EDT_DEF(0, 7, 3)
#undef __EDT_DEF__


#define __TASK_TAG_GET__
#include "AutoGenSupport.hpp"
// const SwarmTagWrapper<SwarmTaskTag<0, 7, 3>> *tag_wrapper = 
//   SwarmTagWrapper<SwarmTaskTag<0, 7, 3> >::
//   _cast_fromAny((swarm_Any_i *)(void *)THIS);
// const SwarmTaskTag<0, 7, 3> &tag = *(tag_wrapper->tInst);
RSTREAM_TASK_TAG_GET(this_stw, tag, 0, 7, 3)
#undef __TASK_TAG_GET__

// const SwarmTagWrapper<SwarmTaskTag<0, 7, 3>> *this_stw = 
//                                      SwarmTagWrapper<SwarmTaskTag<0, 7, 3> >::
//                                      _cast_fromAny((swarm_Any_i *)(void *)THIS);

// #ifdef DEBUG
// SEQUENTIAL_DUMP1("\n\n");
// // RAII style sequentialization
// // Threading::SequentializeCurrentScope sct;
// SEQUENTIAL_DUMP1("Run heat-3d on thread: " << Threading::my_thread_id() 
//                  << " and wrapper @" << this_stw << " with tag " << *(this_stw->tInst));
// #endif



// Suspend on asynchronous gets
#define __TASK_GET__
#include "AutoGenSupport.hpp"
// bool suspend = asyncGets(THIS,
//                          swarm_CodeletDesc_CODELET(WORKER_CODELET_NAME(0,7,3)), 
//                          TAG_TABLE_NAME(0, 7, 3), 
//                          tag);
// //    asyncGets(THIS, swarm_CodeletDesc_CODELET(heat3d), polySwarmTaskTags, this_stw->tInst);
// if (suspend) return;
  RSTREAM_TASK_GET(tag, 0, 7, 3)
#undef __TASK_GET__

{ // Auto-generated polyhedral loops
  int64_t t1 = tag[0];
  int64_t t2 = tag[1];
  int64_t t3 = tag[2];
  int64_t pT = tag[0+3];
  int64_t pM = tag[1+3];
  int64_t pN = tag[2+3];
  int64_t pP = tag[3+3];

  double (*M)[2][Npadded][Npadded][Npadded] = (double (*)[2][Npadded][Npadded][Npadded])(A);
  int64_t t4, t5, t6, t7, t8, lbv, ubv;
  for (t4=max(max(max(0,ceild(t1+t2-124,125)),ceild(16*t2-pN-998,1000)),ceild(16*t3-pN-998,1000));t4<=min(min(min(min(floord(8*t1+pN+7,500),floord(pT+pN-2,1000)),floord(16*t2+pN+14,1000)),floord(16*t3+pN+14,1000)),floord(8*t1+8*t2+pN+15,1000));t4++) {
    for (t5=max(max(max(max(max(0,8*t1+8*t2),16*t1+1),16*t2-pN),16*t3-pN),1000*t4-pN);t5<=min(min(min(min(min(pT-2,16*t2+14),16*t3+14),1000*t4+998),8*t1+8*t2+15),16*t1+pN+15);t5++) {
      if (t5%2 == 0) {
        for (t6=max(max(16*t2,t5+1),-16*t1+2*t5-15);t6<=min(min(-16*t1+2*t5,16*t2+15),t5+pN);t6++) {
          for (t7=max(16*t3,t5+1);t7<=min(16*t3+15,t5+pN);t7++) {
            lbv=max(1000*t4,t5+1);
            ubv=min(1000*t4+999,t5+pN);
#pragma vector always
#pragma ivdep
            for (t8=lbv;t8<=ubv;t8++) {
              M[0][1][-t5+t6][-t5+t7][-t5+t8]=0.125*(M[0][0][-t5+t6+1][-t5+t7][-t5+t8]-2.0*M[0][0][-t5+t6][-t5+t7][-t5+t8]+M[0][0][-t5+t6-1][-t5+t7][-t5+t8])+0.125*(M[0][0][-t5+t6][-t5+t7+1][-t5+t8]-2.0*M[0][0][-t5+t6][-t5+t7][-t5+t8]+M[0][0][-t5+t6][-t5+t7-1][-t5+t8])+0.125*(M[0][0][-t5+t6][-t5+t7][-t5+t8-1]-2.0*M[0][0][-t5+t6][-t5+t7][-t5+t8]+M[0][0][-t5+t6][-t5+t7][-t5+t8+1])+M[0][0][-t5+t6][-t5+t7][-t5+t8];;
            }
          }
        }
      }else{
        for (t6=max(max(16*t2,t5+1),-16*t1+2*t5-15);t6<=min(min(-16*t1+2*t5,16*t2+15),t5+pN);t6++) {
          for (t7=max(16*t3,t5+1);t7<=min(16*t3+15,t5+pN);t7++) {
            lbv=max(1000*t4,t5+1);
            ubv=min(1000*t4+999,t5+pN);
#pragma ivdep
#pragma vector always
            for (t8=lbv;t8<=ubv;t8++) {
              M[0][0][-t5+t6][-t5+t7][-t5+t8]=0.125*(M[0][1][-t5+t6+1][-t5+t7][-t5+t8]-2.0*M[0][1][-t5+t6][-t5+t7][-t5+t8]+M[0][1][-t5+t6-1][-t5+t7][-t5+t8])+0.125*(M[0][1][-t5+t6][-t5+t7+1][-t5+t8]-2.0*M[0][1][-t5+t6][-t5+t7][-t5+t8]+M[0][1][-t5+t6][-t5+t7-1][-t5+t8])+0.125*(M[0][1][-t5+t6][-t5+t7][-t5+t8-1]-2.0*M[0][1][-t5+t6][-t5+t7][-t5+t8]+M[0][1][-t5+t6][-t5+t7][-t5+t8+1])+M[0][1][-t5+t6][-t5+t7][-t5+t8];;
            }
          }
        }
      }
    }
  }
  
// #ifdef DEBUG
//   SEQUENTIAL_DUMP1("Start put codelet on wrapper @" << this_stw << " with tag " << this_tag);
// #endif
  

#define __TASK_PUT__
#include "AutoGenSupport.hpp"
  // swarm_TagTable_put(// &polySwarmTaskTags, 
  //                    &TAG_TABLE_NAME(0, 7, 3),
  //                    this_stw->_cast_toIdentifiable(), 
  //                    NULL, swarm_TagTable_COUNT_IMMORTAL, NULL, NULL);
  RSTREAM_TASK_PUT(this_stw, tag, 0, 7, 3)
#undef __TASK_PUT__

}

// #ifdef DEBUG
// SEQUENTIAL_DUMP1("Done codelet: " << *(this_stw->tInst) << "\n");
// #endif

#define __COUNTING_DEP_SATISFY_ONCE__
#include "AutoGenSupport.hpp"
//swarm_Dep_satisfyOnce(&dep);
RSTREAM_COUNTING_DEP_SATISFY_ONCE(0, 7, 3)
#undef __COUNTING_DEP_SATISFY_ONCE__

#define __EDT_DEF__
#include "AutoGenSupport.hpp"
//swarm_CodeletDesc_IMPL_END;
RSTREAM_END_WORKER_EDT_DEF(0, 7, 3)
#undef __EDT_DEF__
